In computing, an operating system (OS) is software that acts as an interface between the computer hardware and the user, and as such, is responsible for managing and coordinating the requests that user applications make to the computer hardware. FIG. 1 is a diagram illustrating an operating system acting as an interface between the user and the computer hardware. As illustrated at 110 and 120, operating systems divide the software running in the computer into different layers, user space 110 and the kernel 120. Applications running in user space illustrated at 112, 114, and 116 include user software such as a text editors, email programs, and web browsers. Applications running in user space may be referred to as user space applications or user mode applications.
As is well known to those skilled in the art, the kernel 120 comprises the software code that actually runs the computer system. A non-exclusive list of the tasks performed by the kernel includes, managing the code processes for the user mode applications, managing the communications between the hardware and software components, allocating the central processing unit (“CPU”) among the application code processes, handling sensitive resources, managing input/output requests to the hardware, and implementing security. One way in which the kernel 120 implements security and reliability barriers is by preventing user mode applications from directly accessing kernel resources, such as the computer hardware. Operating systems provide different levels of access to resources and only the kernel has privilege to directly access most hardware resources, while user mode applications must in general use kernel services such as system calls. This concept is illustrated in FIG. 1, in which the kernel 120 is shown between user space 110 and the hardware layer 130. The hardware layer consists of the computer hardware, such as one or more processors (CPU's) 136, system memory 137, a storage device, such as a disk 138, busses, such as USB buses 132, 136, and attached peripheral devices, such as USB devices 138, 140, and 142. A user mode application does not have permission to access the underlying computer resources, such as printers, flash drives, or other peripherals attached to the computer. Thus, a user mode application cannot directly perform operations that it needs, such as input/output “I/O” operations to a device attached to the system, e.g. a printer or flash drive. A user mode application must therefore make requests to the operating system to perform those tasks that it does not have the requisite permissions to execute. These requests are referred to as system calls, which provide the interface between a process in a user mode application and a service that the kernel provides. System calls are illustrated at 150, 152, 154, 156, and 158 of FIG. 1. For example, a user mode application may want to read a file from a flash drive. Because the user mode application cannot directly access the flash drive it will make a system call to the kernel, such as the “read” system call. The kernel will then translate the system call into an I/O command, send that request to the hardware, receive data from the hardware, and return the data to the user mode application. I/O commands from the kernel to the hardware layer are illustrated at 170, 172, and 174 of FIG. 1. System calls include open, read, write, and IOCTLs. As indicated by their names, open will open a hardware device; read will read data from a device; write will write data to a device; and exit will exit the use of a device. IOCTL system calls are described in more detail below.
USB
As illustrated at 130 of FIG. 1, the hardware layer of a computer may include the hardware in the computer such as the busses, and peripheral devices 138, 140 and 142 that are attached to the computer. Peripheral devices may be attached to a computer using the USB (“Universal Serial Bus.”) protocol. The USB protocol allows a variety of peripherals devices such as mice, keyboards, digital cameras, printers, personal media players, flash drives, smartphones and PDAs to be attached to the USB through a consistent interface. As illustrated in FIG. 1, USB peripheral devices 138, and 140, are attached to USB Bus001 132 through host controllers 180, and 182. Peripheral device 142 is attached to USB Bus002 134 through host controller 184. The host controllers 180, 182, and 184 connect the host computer system to the USB devices.
Because there are a variety of devices that can be attached to the computer system through USB and other methods, it is useful to have specific software modules to control I/O to specific devices, rather than having to program the kernel so that it knows how to handle the I/O for every device that may be attached to the computer. Additionally, new devices are always being developed, and thus, the kernel cannot be programmed to control every possible device that may be attached to the computer. These software modules are referred to as “device drivers” or simply “drivers.” A driver acts as a translator that converts the more general I/O instructions of the operating system to messages that can be understood by a specific device type with which that driver is associated. One family of drivers is the kernel mode USB drivers, which are loaded by the kernel and run with full privilege. There are also user mode applications programmed to control USB devices, which are referred to as “user mode USB drivers.” User mode USB drivers run with user privilege, and thus, must communicate with USB devices via system calls to the kernel.
Kernel Mode USB Drivers
FIG. 2A is a diagram illustrating kernel mode drivers for USB devices. As illustrated in FIG. 2A kernel mode USB drivers 200, 202, and 204 run in kernel space. User mode applications 112, 114, and 116 make system calls 150, 152, 154, 156 and 158 to the kernel mode USB drivers 200, 202, and 204. The kernel mode drivers then translate the system calls to specific I/O commands 210, 212, 214, 216 and 218 for the specific type of devices with which they are associated. In the example illustrated in FIG. 2A kernel mode USB driver 200 is associated with USB device 138, kernel mode USB driver 202 with USB device 140, and kernel mode USB driver 204 with USB device 142. As example of this process, user mode application 112 could be a text editor application needing to save a document to USB device 138 which could be a USB flash drive. The text editor might issue a write system call to the USB driver 200 associated with the flash drive 138. Device driver 200 would then translate the system call to a specific I/O command 210 to the USB device 138. For simplicity, FIG. 2A illustrates one kernel mode USB driver for each user mode application and USB device. However, different user mode applications may use the same kernel mode USB driver. For example, both a text editor and a browser may use the same kernel mode USB driver to send output to the same printer. Also, two devices may be claimed by the same kernel mode USB driver. For example, both a mouse and a keyboard may be claimed by the same USB HID driver discussed below.
An example of a kernel mode USB driver includes, but is not limited to, the USB (Human Interface Diver) (“HID”), which supports human interfaces devices such as keyboards and mice. Another example is the USB storage device driver, which is a kernel mode driver that supports devices such as disks, flash drives, floppy drives, cd roms, and other types of storage. There are also USB host controller drivers in the kernel which control USB host controllers. As explained above and as illustrated at 180, 182 and 184 of FIG. 2A host controllers connect the host computer system to the USB devices. There may be additional USB drivers in the kernel that are written for specific devices. For example, USB drivers that correspond to specific vendors and models of the various peripheral devices such as printers, video cameras, phones, etc. may be added to the kernel. There is a data structure in the kernel core library that stores an entry for every kernel mode USB driver in the system. FIG. 2B is a diagram illustrating such as data structure for the system depicted in FIG. 2A with kernel mode USB drivers 200, 202, and 204.
In order for a kernel mode USB driver to interface with a specific USB device, the device must be “claimed” by the driver. For example, if the device is a keyboard or mouse, the HID device driver may claim the device. The method for a device to be claimed by a kernel mode USB driver is well known in the art of computer software. To provide an illustrative example, FIG. 3A is a flow chart depicting the method in an operating system which uses a probe routine in the kernel mode USB driver to claim a device. Such operating systems include, but are not limited to, UNIX, LINUX, and VMware® ESX offered by VMware Inc. of Palo Alto, Calif.
At step 302, notification is received that a USB device has been newly attached to the system. Operating systems are programmed to provide a notification to the kernel whenever a new USB device is attached to a bus. At step 304, the device is presented to the first registered kernel mode USB driver in the data structure that stores device drivers illustrated at 250 of FIG. 2B.
At step 306 it is determined whether the USB driver matches the device that has been presented. In an operating system using probe routines, each kernel mode USB driver contains a probe routine that queries the device to determine whether there is a match, i.e. whether the driver recognizes the device as a device with which it knows how to interface. When the device is presented to a kernel mode driver in the data structure illustrated in FIG. 2B, the kernel core library calls the probe routine for that driver. If the probe routine recognizes the device, it can “claim” the device and take over its I/O management. For example, a mouse would match a HID driver, and a specific make and model of a printer would match the driver with that specific make and model.
As shown in 308, if the device matches the driver, the driver “claims” the device, i.e. the device is marked as being claimed by the driver and this method ends. Marking a device as claimed by a driver may be done by indicating the kernel mode driver claiming the device in a data structure for the device as is well known in the art. For example, in some operating systems including, but not limited to UNIX, LINUX, and VMware® ESX, when a new USB device is attached to the system, the kernel core library creates a data structure for that device and begins filling information about the device into the data structure. FIG. 3B is a diagram illustrating the data structure for USB Device 138 of FIG. 2A. As shown at 352, one field in the data structure indicates which kernel mode USB driver claims the device.
If the device does not match the driver, then at 310 it is determined if there are any more kernel mode USB drivers to which the device should be presented, i.e. whether there are any further kernel mode drivers in the data structure depicted in FIG. 2B to which the device has not been presented. If there is an additional kernel mode USB driver in the data structure at 312 in FIG. 3A, the newly attached device is presented to the next driver in the data structure sequentially, and the method repeats steps 306 and continues.
If there are no further kernel mode USB drivers in the data structure, then at 314 the device is placed in a queue of devices to which there are no register matching kernel mode USB drivers and then presented to any newly added kernel mode USB drivers.
Thus, if there is a kernel mode USB driver on the system that matches a newly attached device, it is deterministically decided that the particular USB driver will claim the device, and be allowed to issue I/O commands to that device. This claiming method is robust, meaning that other kernel mode USB drivers on the system will not be allowed to control the device while it is claimed by the kernel mode USB driver.
User Mode Device Drivers
As opposed to kernel mode drivers, user mode drivers run in user space. FIG. 4A is a diagram illustrating user mode USB drivers. Like kernel mode drivers, user mode drivers control specific types of USB devices attached to the system. FIG. 4A depicts user mode drivers 117, 118, and 120 running in user space. Just like any other user mode driver, USB user mode drivers issue open, close, read, write and IOCTL (short for “I/O control”) system calls to the kernel. Unlike most other user mode drivers, user mode USB drivers use the IOCTL system call as illustrated at 402, 404, and 406, for both control I/O and data I/O. IOCTLs are generic system calls that allow user mode applications to communicate with kernel modules and perform arbitrary device specific operations; and thereby pass information that is specific to a particular device. Each IOCTL command contains a device specific subcommand that controls how the kernel interprets the command. In the case of USB IOCTLs these subcommands are USB specific and include commands to transmit “bulk”, “control” and “interrupt” data to/from a USB device (e.g., USBDEVFS_BULK) as well as more conventional “device control” subcommands such as the one to reset the USB device (USBDEVFS_RESET) and a host of others which are well known to those skilled in the art. Thus IOCTL system calls to USB devices are translated into both control as well as regular I/O to the USB devices. Therefore, the same IOCTL may be used by different user mode drivers to communicate different types of information to different devices, making them particularly useful for user mode devices drivers.
Implementing user mode drivers is well known in the art of computer software. As an illustrative example, many operating systems, including but are not limited to, UNIX, LINUX, and VMware® ESX, allow for implementing user mode drivers through their device files as illustrated at 430, 432, and 434 of FIG. 4. In such operating systems there is a dynamic file system in the kernel that presents a view into the device structure of the actual physical hardware of the devices attached to the system.
Each file in the file system corresponds to a device attached to the computer. The kernel presents the I/O interface for each device as a file, such that reading and writing to the device may be performed using the same format as reading and writing to a file. For USB devices this file system is often referred to as the USB file system or simply “usbfs.” Devices that can be accessed as a stream of bytes, such as printers, cameras, smartphones, are referred to as character devices, with the files corresponding to each of these devices referred to as “chardev” files. In Linux systems, the usbfs is generally mounted in the /proc file system, which provides information about all running processes in the system. Therefore, the device files are often referred to in Linux as “proc nodes.” FIG. 4B is a diagram illustrating an example of a usbfs in Linux for the USB devices illustrated at 138, 140, and 142 of FIGS. 1, 2A and 4.
The /proc/bus/usb/devices file contains a list of all USB devices attached at that moment in time, and provides other USB-specific information about each device. The file/proc/bus/usb/001/001 FIG. 4B at 452 would be the device file for USB device 138, and would include information about that device. The file/proc/bus/usb/002/001 FIG. 4B at 458 would be the device file for USB device 142. These device files support a wide range of IOCTL calls that allow user mode applications to send and receive USB data from the device, and thus are useful to user mode USB drivers.
Because usbfs presents the I/O interface for each device as a file, reading and writing to the device may be performed using the same format as reading and writing to a file. Therefore, some user mode drivers may read and write to devices by issuing system calls such as IOCTLs to the device file as depicted at 430, 432, and 434 of FIG. 4A. Writes to device files are translated into the actual output to the device. In the case of USB user mode drivers all writes to USB devices are issued via IOCTLs using the aforementioned “bulk”, “control” and “interrupt” subcommands. One method for writing user mode USB drivers is to write them using Libusb. Libusb is a library that works on a variety of different operating systems including Linux, BSD and Mac OS X. As illustrated at FIG. 4A at 420, Libusb is an interface between a user mode USB driver and the kernel. Libusb translates user mode functions into IOCTLs and other system calls that must be made to the kernel in order to implement the functions in the user mode USB driver. Libusb conceals the low-level kernel interactions with the USB modules. It provides a set of functions which are adequate to develop a device driver for a USB device in user space.
As opposed to the method used by kernel mode USB drivers for claiming a device, user mode USB drivers may claim a device, i.e. gain control of that device, simply by opening the device for write, i.e. opening the device file in order to perform a write to the device. As explained above, the process for a kernel mode USB driver to claim a device allows for robust sharing of devices between entities, meaning that while one kernel mode USB driver has claimed a device, no other kernel mode USB driver may interrupt the I/O process of the kernel mode device driver on the device. In contrast, a user mode USB driver may claim a device that another entity is currently using, without even notifying the entity and allowing it to shut down its session cleanly. The other entity may be a kernel mode driver or another user mode driver. For example, it is possible to abort a filecopy to a USB storage device by use of a simple libusb program as illustrated in FIG. 5. The usbChardev test shown in the right hand window 504 run on the host terminal aborted a filecopy on a storage device attached to a virtual machine as shown at 502. For USB there is an additional problem. USB devices are arranged hierarchically, i.e. in a tree structure with devices connected to a hub. If hubs and host controllers are not protected from a user mode USB driver then it is possible to bring down all of the USB devices on a hub even if the device itself were to be protected against user mode drivers.
While user mode drivers present a problem when they gain control of a device by opening the device for a write, they do not create such a problem when they issue read-safe IOCTLs to the device, i.e., IOCTLs that access a device to read from the device and that have been determined to not interfere with other drivers, whether kernel mode or user mode, accessing the device. It is useful to allow limited access to all devices for read-safe IOCTLs. Therefore, it would be useful to have systems and methods for preventing a user mode USB driver from claiming a USB device that is claimed by a USB kernel driver or in use by another user mode USB driver, and performing operations on that device other than read-safe IOCTLs.